;   # win key
;   ! alt
;   ^ ctrl
;   + shift
;   $RButton $#RButton $!RButton $+RButton $+! etc
;   $LButton

HotKey, +^!Up, TestMe
HotKey, #Home, TopLeft
HotKey, #Pgup, TopRight
HotKey, #Pgdn, BottomRight
HotKey, #End, BottomLeft
HotKey, #^Left, WindowLeft
HotKey, #^Right, WindowRight
HotKey, #^Up, WindowTop
HotKey, #^Down, WindowBottom
HotKey, #^+Left, ToMonitorLeft 
HotKey, #^+Right, ToMonitorRight
if (A_OSVersion!="WIN_7")
{
  HotKey, #Up, WindowUp
  HotKey, #Down, WindowDown 
  HotKey, #Left, WindowLeft
  HotKey, #Right, WindowRight
  HotKey, #+Left, ToMonitorLeft 
  HotKey, #+Right, ToMonitorRight
}
HotKey, ^!+r, DoReload
Return

DoReload:
  Reload
  Sleep 1000 ; If successful, the reload will close this instance during the Sleep, so the line below will never be reached.
;  MsgBox, 4,, The script could not be reloaded. Would you like to open it for editing?
;  IfMsgBox, Yes, Edit
  return


TestMe:
  SysGet, MonitorCount, 80
  Loop, %MonitorCount%
  {
    SysGet, MonitorWorkArea, MonitorWorkArea, %A_Index%
    MsgBox %MonitorWorkAreaLeft%, %MonitorWorkAreaTop%, %MonitorWorkAreaRight%, %MonitorWorkAreaBottom%
  }
Return

;WinMove, WinTitle, WinText, X, Y [, Width, Height, ExcludeTitle, ExcludeText]
;WinTitle=A && WinText="" :  Move active window

TopLeft:
  ;MoveTo(0, 0, (A_ScreenWidth/2), (A_ScreenHeight/2))
  SetBounds(0, 0, 50, 50) 
Return

TopRight:
  ;MoveTo((A_ScreenWidth/2), 0, (A_ScreenWidth/2), (A_ScreenHeight/2))
  SetBounds(50, 0, 50, 50)
Return

BottomRight:
  ;MoveTo((A_ScreenWidth/2), (A_ScreenHeight/2), (A_ScreenWidth/2), (A_ScreenHeight/2))
  SetBounds(50, 50, 50, 50)
Return

BottomLeft:
  ;MoveTo(0, (A_ScreenHeight/2), (A_ScreenWidth/2), (A_ScreenHeight/2))
  SetBounds(0, 50, 50, 50)
Return


WindowTop:
  ;MoveTo(0, 0, (A_ScreenWidth), (A_ScreenHeight/2))
  SetBounds(0, 0, 100, 50)
Return

WindowBottom:
  ;MoveTo(0, (A_ScreenHeight/2), (A_ScreenWidth), (A_ScreenHeight/2))
  SetBounds(0, 50, 100, 50)
Return

WindowLeft:
  ;MoveTo(0, 0, (A_ScreenWidth/2), (A_ScreenHeight))
  SetBounds(0, 0, 50, 100)
Return
  
WindowRight:
  ;MoveTo((A_ScreenWidth/2), 0, (A_ScreenWidth/2), (A_ScreenHeight))
  SetBounds(50, 0, 50, 100)
Return

ToMonitorLeft:
  WinGetPos, cLeft, cTop, cRight, cBottom, A  
  SysGet, MonitorCount, 80
  VirtualWidth := GetVirtualWidth()
  
  if (cLeft < 0)
  {
    nLeft := cLeft + VirtualWidth
  }
  else if (cLeft > VirtualWidth)
  {
    nLeft := cLeft - VirtualWidth
  }
  else
  { 
    CurMonitorIndex := 0
    Loop, %MonitorCount%
    {
      SysGet, MonitorWorkArea, MonitorWorkArea, %A_Index%
      MonitorLeft%A_Index% := MonitorWorkAreaLeft
      if ((MonitorWorkAreaLeft <= cLeft) && (cLeft < MonitorWorkAreaRight))
      {
        CurMonitorIndex := A_Index
      }
    }
    NewMonitorIndex := CurMonitorIndex - 1
    if (NewMonitorIndex <= 0)
      NewMonitorIndex := MonitorCount
      
    nLeft := cLeft - MonitorLeft%CurMonitorIndex% + MonitorLeft%NewMonitorIndex%
    if (nLeft < 0)
    {
      nLeft := nLeft + VirtualWidth
    }
    else if (nLeft > VirtualWidth)
    {
      nLeft := nLeft - VirtualWidth
    }
  }
  
  WinMove,A,, nLeft, cTop, cRight, cBottom  
Return



ToMonitorRight:
  WinGetPos, cLeft, cTop, cRight, cBottom, A  
  SysGet, MonitorCount, 80
  VirtualWidth := GetVirtualWidth()
  
  if (cLeft < 0)
  {
    nLeft := cLeft + VirtualWidth
  }
  else if (cLeft > VirtualWidth)
  {
    nLeft := cLeft - VirtualWidth
  }
  else
  { 
    CurMonitorIndex := 0
    Loop, %MonitorCount%
    {
      SysGet, MonitorWorkArea, MonitorWorkArea, %A_Index%
      MonitorLeft%A_Index% := MonitorWorkAreaLeft
      if ((MonitorWorkAreaLeft <= cLeft) && (cLeft < MonitorWorkAreaRight))
      {
        CurMonitorIndex := A_Index
      }
    }
    NewMonitorIndex := CurMonitorIndex + 1
    if (NewMonitorIndex > MonitorCount)
      NewMonitorIndex := 1
      
    nLeft := cLeft - MonitorLeft%CurMonitorIndex% + MonitorLeft%NewMonitorIndex%
    if (nLeft < 0)
    {
      nLeft := nLeft + VirtualWidth
    }
    else if (nLeft > VirtualWidth)
    {
      nLeft := nLeft - VirtualWidth
    }
  }
  
  WinMove,A,, nLeft, cTop, cRight, cBottom
Return



WindowUp:
  WinMaximize, A
Return

WindowDown:
  WinRestore, A 
Return

GetVirtualWidth()
{
  SysGet, Result, 78
  return Result
}
GetVirtualHeight()
{
  SysGet, Result, 79
  return Result
}



SetBounds(leftPer, topPer, rightPer, bottomPer)
{
  WinGetPos, cLeft, cTop, cRight, cBottom, A
  
  SysGet, MonitorCount, 80
  Loop, %MonitorCount%
  {
    SysGet, MonitorWorkArea, MonitorWorkArea, %A_Index%
    if (cLeft < MonitorWorkAreaRight)
    {
      break
    }
  }
  nLeft := MonitorWorkAreaLeft + (MonitorWorkAreaRight - MonitorWorkAreaLeft) * leftPer / 100
  nTop  := MonitorWorkAreaTop + (MonitorWorkAreaBottom - MonitorWorkAreaTop) * topPer / 100
  nRight := (MonitorWorkAreaRight - MonitorWorkAreaLeft) * rightPer / 100
  nBottom := (MonitorWorkAreaBottom - MonitorWorkAreaTop) * bottomPer / 100  
  WinMove,A,, nLeft, nTop, nRight, nBottom
  ;MsgBox %cLeft%, %cTop%, %cRight%, %cBottom%`n%nLeft% := %MonitorWorkAreaLeft% * %leftPer% / 100`n%nTop% := %MonitorWorkAreaTop% * %TopPer% / 100`n%nRight% := %MonitorWorkAreaRight% * %RightPer% / 100`n%nBottom% := %MonitorWorkAreaBottom% * %BottomPer% / 100
}  


MoveTo(x, y, w, h)
{
  WinGetPos, Left, Top, Width, Height, A
  SysGet, MonitorCount, 80
  Loop, %MonitorCount%
  {
    SysGet, MonitorWorkArea, MonitorWorkArea, %A_Index%
    if ((MonitorWorkAreaLeft <= Left) && (Left <= MonitorWorkAreaRight))
    {
      x := x + MonitorWorkAreaLeft
      break
    }
  }
  WinMove,A,, x, y, w, h
}  